package 设计模式.结构型.代理模式.静态代理.implements实现2;

import org.omg.PortableInterceptor.RequestInfo;
import 设计模式.结构型.代理模式.静态代理.最初的需求1.MetricsCollector;
import 设计模式.结构型.代理模式.静态代理.最初的需求1.UserVo;

/**
 * 代理功能实现类
 *
 * UserControllerProxy使用举例
 * 因为原始类和代理类实现相同的接口，是基于接口而非实现编程
 * 将UserController类对象替换为UserControllerProxy类对象，不需要改动太多代码
 *
 * 这里其实就需要让客户端调用的时候，调用成本类，如果开始客户端调用的是原本的UserController方法，
 * 就需要客户端从 UserController 方法调用改成调用 UserControllerProxy.
 *
 * 因为 UserController 和 UserControllerProxy 有共同的接口，所以在客户端不需要做太多的改动就可以做到。
 *
 * 参照基于接口而非实现编程的设计思想，将原始类对象替换为代理类对象的时候，为了让代码改动尽量少，在刚刚的代理模式的代码实现中，代理类和原始类需要实现相同的接口。
 * 但是，如果出现一种场景：
 *      如果原始类并没有定义接口，并且原始类代码并不是我们开发维护的（比如它来自一个第三方的类库），我们也没办法直接修改原始类，给它重新定义一个接口。在这种情况下，我们该如何实现代理模式呢？
 *      这种场景的解决办法就是通过 extends 来实现。
 *
 *
 */
public class UserControllerProxy implements IUserController {

    private MetricsCollector metricsCollector;
    private UserController userController;

    public UserControllerProxy(UserController userController) {
        this.userController = userController;
        this.metricsCollector = new MetricsCollector();
    }

    @Override
    public UserVo login(String telephone, String password) {
        long startTimestamp = System.currentTimeMillis();
        // 委托
        UserVo userVo = userController.login(telephone, password);
        long endTimeStamp = System.currentTimeMillis();
        long responseTime = endTimeStamp - startTimestamp;
        RequestInfo requestInfo = null;
        // new RequestInfo("login", responseTime, startTimestamp);
        metricsCollector.recordRequest(requestInfo);
        return userVo;
    }

    @Override
    public UserVo register(String telephone, String password) {
        long startTimestamp = System.currentTimeMillis();
        UserVo userVo = userController.register(telephone, password);
        long endTimeStamp = System.currentTimeMillis();
        long responseTime = endTimeStamp - startTimestamp;
        RequestInfo requestInfo = null;
        // new RequestInfo("register", responseTime, startTimestamp);
        metricsCollector.recordRequest(requestInfo);
        return userVo;
    }
}
